#include "btn_event.h"
#include "client.h"
#include "bq.h"
#include "time.h"

extern lv_obj_t *scr1;
extern lv_obj_t *scr2;
extern lv_obj_t *scr3;
extern lv_obj_t *img;
extern lv_obj_t *mbox3;
extern lv_obj_t *ta1;
extern lv_obj_t *ta2;
extern lv_obj_t *ta3;
extern lv_obj_t *ta4;
extern lv_obj_t *ta5;
extern lv_obj_t *ta6;
extern char account[50];
extern char password[50];
extern char sendbuf[100];
extern int tcpsock;
extern int udpsock;
extern struct clientlist *clienthead; // 客户端链表头指针
extern lv_obj_t *list;
static lv_style_t rightstyle;
lv_obj_t *btnfriend;
char ip[20];
int port;
struct sockaddr_in otheraddr; // 另一个客户端地址
extern lv_obj_t *btn;         // 列表按钮

void group_chat(lv_event_t *e) // 点击群发
{
  const char *text3 = lv_textarea_get_text(ta5);
  bzero(sendbuf, sizeof(sendbuf));
  sprintf(sendbuf, "groupchat@%s", text3);
  // 将text3发送给服务器
  send(tcpsock, sendbuf, strlen(sendbuf), 0);
}

void chat_page() // 登录事件，创建一个聊天页面
{
  // 创建一个页面
  printf("chat_page\n");
  scr3 = lv_obj_create(lv_scr_act());
  lv_obj_set_size(scr3, 800, 480);
  // 设置界面位置，居中
  lv_obj_center(scr3);
  lv_obj_t *img_s = lv_img_create(scr3);
  LV_IMG_DECLARE(island); // 声明图片，不是.c里面数组的名字，是结构体的名字

  // 图片对象必须跟某张具体的图片关联
  lv_img_set_src(img_s, &island);
  lv_obj_center(img_s);
  // 在页面左侧创建一个列表，代表好友列表
  list = lv_list_create(scr3);
  lv_obj_set_size(list, 180, 380);
  lv_obj_align(list, LV_ALIGN_LEFT_MID, 0, 0);
  // 给列表设置标签，代表好友列表
  lv_list_add_text(list, "Friend List");
  // 给列表添加按钮，刷新好友列表
  btn = lv_list_add_btn(list, LV_SYMBOL_REFRESH, "Refresh");
  // 给这个按钮添加点击事件，刷新好友列表
  lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);

  // 在页面正下角设置一个按钮，用来表示群发消息给所有客户端
  btn = lv_btn_create(scr3);
  lv_obj_set_size(btn, 100, 50);
  lv_obj_align(btn, LV_ALIGN_BOTTOM_MID,130, -98);
  lv_obj_t *label8 = lv_label_create(btn);
  lv_label_set_text(label8, "Group");
  lv_obj_add_event_cb(btn, group_chat, LV_EVENT_CLICKED, NULL);
  // 在页面偏右下角创建一个文本区域，代表输入区域
  ta5 = lv_textarea_create(scr3);
  lv_obj_set_size(ta5, 200, 100);
  lv_obj_align(ta5, LV_ALIGN_BOTTOM_RIGHT, -350, -100);
  // 在页面偏右上角创建一个横向列表区域，代表聊天显示框，里面有聊天内容
  ta6 = lv_list_create(scr3);
  lv_obj_set_size(ta6, 350, 200);
  lv_obj_align(ta6, LV_ALIGN_TOP_RIGHT, -200, 27);
  // 在ta5文本区域下方设置一个按钮，代表，发送信息
  lv_obj_t *btn1 = lv_btn_create(scr3);
  lv_obj_set_size(btn1, 100, 50);
  lv_obj_align(btn1, LV_ALIGN_BOTTOM_RIGHT, -200, -152);
  lv_obj_t *label1 = lv_label_create(btn1);
  lv_label_set_text(label1, "Send");
  // 在页面正下角设置一个时间标签，显示当前时间
  lv_time();

  // //在页面右下角设置一个标签，写上hello
  // lv_obj_t * hellolabel = lv_label_create(scr3);
  // lv_obj_align(hellolabel, LV_ALIGN_BOTTOM_MID, 0, -20);
  // show_chinese(20,hellolabel);
  // lv_label_set_text(hellolabel, "Hello~~~");

  // //在页面正下方设置一个标签，写上"心动聊天室”
  // lv_obj_t * label2 = lv_label_create(scr3);
  // lv_obj_align(label2, LV_ALIGN_BOTTOM_MID, 0, 0);
  // show_chinese(20,label2);
  // lv_label_set_text(label2, "心动聊天室");

  // 给发送按钮设置事件响应函数
  lv_obj_add_event_cb(btn1, send_event_cb, LV_EVENT_CLICKED, NULL);
  // 在页面右下角设置一个menu，代表表情包列表
  lv_obj_t *menu = lv_menu_create(scr3);
  lv_obj_set_size(menu, 180, 150);
  lv_obj_align(menu, LV_ALIGN_TOP_RIGHT, 0, 0);
  lv_obj_t *cont;
  lv_obj_t *label;

  /*Create a sub page*/
  lv_obj_t *sub_page = lv_menu_page_create(menu, NULL); // 创建一个子页面，它的父对象是菜单对象，标题为 NULL（无标题）。

  cont = lv_menu_cont_create(sub_page);              // 在子页面中创建一个新的容器对象。
  label = lv_label_create(cont);                     // 在容器对象中创建一个标签。
  lv_label_set_text(label, "Please choose a Emoji"); // 设置标签的文本内容。

  cont = lv_menu_cont_create(sub_page); // 在子页面中创建一个新的容器对象。
  btn = lv_btn_create(cont);            // 在容器对象中创建一个按钮。
  // 设置按钮大小
  lv_obj_set_size(btn, 160, 144);
  // 给按钮设置图片源
  lv_obj_t *img1 = lv_img_create(btn);
  // 设置图片位置
  lv_obj_align(img1, LV_ALIGN_CENTER, 0, 0);
  // 声明图片
  LV_IMG_DECLARE(bq1);
  // 图片源与图片绑定
  lv_img_set_src(img1, &bq1);
  // 给这个按钮设置事件响应函数
  lv_obj_add_event_cb(btn, emoji1, LV_EVENT_CLICKED, NULL);

  cont = lv_menu_cont_create(sub_page); // 在子页面中创建一个新的容器对象。
  btn = lv_btn_create(cont);            // 在容器对象中创建一个按钮。
  // 设置按钮大小
  lv_obj_set_size(btn, 160, 144);
  // 给按钮设置图片源
  lv_obj_t *img2 = lv_img_create(btn);
  // 设置图片位置
  lv_obj_align(img2, LV_ALIGN_CENTER, 0, 0);
  // 声明图片
  LV_IMG_DECLARE(bq2);
  // 图片源与图片绑定
  lv_img_set_src(img2, &bq2);
  // 给这个按钮设置事件响应函数
  lv_obj_add_event_cb(btn, emoji2, LV_EVENT_CLICKED, NULL);

  
  /*Create a main page*/
  lv_obj_t *main_page = lv_menu_page_create(menu, NULL); // 创建一个主页面，它的父对象是菜单对象，标题为 NULL（无标题）。

  cont = lv_menu_cont_create(main_page);             // 在主页面中再创建一个新的容器对象。
  label = lv_label_create(cont);
   lv_obj_set_style_bg_color(main_page, lv_color_hex(0xf28e16), LV_STATE_DEFAULT);
  lv_obj_set_style_bg_opa(main_page, 100, LV_STATE_DEFAULT); //透明度0--255，值越大，上面的红色背景越深                     // 在容器对象中再创建一个标签。
  lv_label_set_text(label, "Emoji List");            // 设置标签的文本内容为 表情包列表。
  lv_menu_set_load_page_event(menu, cont, sub_page); // 当点击 表情包列表 时，加载子页面。

  lv_menu_set_page(menu, main_page); // 将主页面设置为菜单的当前显示页面。
}

void chosefriend(lv_event_t *e) // 点击好友按钮表示与这个好友聊天
{
  // 传过来了clientbuf,里面存储着这个按钮代表的客户端信息，格式是ip:端口号
  char *clientbuf = (char *)lv_event_get_user_data(e);
  printf("clientbuf:%s\n", clientbuf);
  // 将clientbuf中的ip和端口号提取出来
  char *ip = strtok(clientbuf, ":");
  printf("ip:%s\n", ip);
  char *port1 = strtok(NULL, ":");
  printf("port:%s\n", port1);
  // 如果这时候没有端口号就不执行接下来的操作
  if (port1 == NULL)
  {
    return;
  }
  // 将端口号字符串转换成整型
  int port2 = atoi(port1);
  printf("port2:%d\n", port2);
  printf("ip:%s,port:%d\n", ip, port2);
  // 此时ip存在ip中，端口号存在port2中
  // 把ip和端口号存入全局变量otheraddr中，用于后续的连接
  bzero(&otheraddr, sizeof(otheraddr));
  otheraddr.sin_family = AF_INET;
  otheraddr.sin_port = htons(port2);
  otheraddr.sin_addr.s_addr = inet_addr(ip);
}

void event_return(lv_event_t *e)
{
  // 用户点击了返回按钮，则返回到登录界面
  lv_obj_del(scr2);
}

void mbox_event_cb(lv_event_t *e)
{
  // 用户点击了关闭按钮，连接服务器
  sc_init(); // 连接服务器
  // 关闭消息盒子
  lv_msgbox_close(mbox3);
}

// 用户点击了注册按钮，则调用该函数
void event_register(lv_event_t *e)
{
  // 用户此时输入了要注册的账号密码,账号存储在txt1中，密码存储在txt2中
  // 创建TCP套接字，连接到服务器，将账号密码发送给服务器，服务器进行注册操作
  // 获取输入的  账号和密码
  const char *txt1 = lv_textarea_get_text(ta3);
  const char *txt2 = lv_textarea_get_text(ta4);
  bzero(account, 50);
  bzero(password, 50);
  strcpy(account, txt1);  // 将账号保存到全局变量account中
  strcpy(password, txt2); // 将密码保存到全局变量password中
  // 将账号密码拼接
  bzero(sendbuf, 100);
  sprintf(sendbuf, "%s@%s@%s", "usrlist", account, password);
  // sc_init();//创建客户端并连接服务器
  sc_send(); // 发送注册信息给服务器审核

  // sc_close();//关闭客户端
}

// 判断账号密码是否正确
// 如果正确，则刷新界面跳转到聊天页面，否则弹出提示框提示账号密码错误
void bt1_cb(lv_event_t *e)
{
  // 用户点击登录按钮，获取输入的账号密码
  // 获取输入的  账号和密码
  const char *txt1 = lv_textarea_get_text(ta1);
  const char *txt2 = lv_textarea_get_text(ta2);
  strcpy(account, txt1);  // 将账号保存到全局变量account中
  strcpy(password, txt2); // 将密码保存到全局变量password中
  // 将账号密码拼接
  bzero(sendbuf, 100);
  sprintf(sendbuf, "%s@%s@%s", "usrlogin", account, password);
  // 发送账号密码给服务器
  sc_send(); // 发送登录信息给服务器审核
}

// 点击注册按钮，跳转到注册页面
void bt2_cb(lv_event_t *e)
{
  // 刷新界面跳转到注册页面
  // 创建一个界面，这个界面是用户注册界面，有注册按钮和返回按钮
  scr2 = lv_obj_create(img);
  // 设置界面大小
  lv_obj_set_size(scr2, 480, 320);
  // 设置界面位置，居中
  lv_obj_center(scr2);
  // 设置界面背景色,浅绿色
  lv_obj_set_style_bg_color(scr2, lv_color_hex(0x00FF00), 0);
  // 创建一个文本输入框，用于输入账号
  ta3 = lv_textarea_create(scr2);
  lv_obj_set_pos(ta3, 140, 50);
  lv_obj_set_size(ta3, 200, 50);
  // 给文本框设置一个标签提示，放在文本框左侧，提示用户输入账号
  lv_obj_t *label2 = lv_label_create(scr2);
  lv_label_set_text(label2, "Account:");
  lv_obj_set_pos(label2, 50, 60);

  // 创建一个文本输入框，用于输入密码
  ta4 = lv_textarea_create(scr2);
  lv_obj_set_pos(ta4, 140, 100);
  lv_obj_set_size(ta4, 200, 50);
  // 给文本框设置一个标签提示，放在文本框左侧，提示用户输入密码
  lv_obj_t *label3 = lv_label_create(scr2);
  lv_label_set_text(label3, "Password:");
  lv_obj_set_pos(label3, 50, 110);

  // 创建一个按钮，用于注册
  lv_obj_t *btn1 = lv_btn_create(scr2);
  lv_obj_set_pos(btn1, 100, 150);
  lv_obj_set_size(btn1, 100, 50);
  lv_obj_t *label4 = lv_label_create(btn1);
  lv_label_set_text(label4, "Register");
  // 创建一个按钮，用于返回
  lv_obj_t *btn2 = lv_btn_create(scr2);
  lv_obj_set_pos(btn2, 250, 150);
  lv_obj_set_size(btn2, 100, 50);
  lv_obj_t *label5 = lv_label_create(btn2);
  lv_label_set_text(label5, "Return");
  // 给这个返回按钮设置事件响应函数，当用户点击这个按钮，可以关掉这个界面，返回登录界面
  lv_obj_add_event_cb(btn2, event_return, LV_EVENT_CLICKED, NULL);
  // 给这个注册按钮设置事件响应函数，当用户点击这个按钮，可以跳转到注册界面
  lv_obj_add_event_cb(btn1, event_register, LV_EVENT_CLICKED, NULL);
}

void send_event_cb(lv_event_t *e)
{
  // 用户点击了发送按钮，那就读取文本框里面的内容，然后发送给指定的客户端
  // 指定的客户端存储在全局变量otheraddr中
  const char *text3 = lv_textarea_get_text(ta5);
  char chatbuf[1024];
  bzero(chatbuf, sizeof(chatbuf));
  bzero(sendbuf, sizeof(sendbuf));
  strcpy(chatbuf, text3); // 复制到sendbuf中
  lv_style_init(&rightstyle);
  lv_style_set_text_align(&rightstyle, LV_TEXT_ALIGN_RIGHT);
  // 创建一个标签，用于显示发送的信息
  lv_obj_t *label6 = lv_label_create(ta6);
  // 设置标签大小
  lv_obj_set_size(label6, 300, 20);
  // 设置标签样式
  lv_obj_add_style(label6, &rightstyle, 0);
  // 设置标签内容
  lv_label_set_text(label6, chatbuf);
  // 将标签滚动到视图
  lv_obj_scroll_to_view(label6, LV_ANIM_ON);

  // 拼接一下发送信息，拼接标志位，代表这是一个发送信息
  sprintf(sendbuf, "%s@%s", "Send", chatbuf); // 拼接标志位
  // 发送给指定的客户端，通过UDP
  sendto(udpsock, sendbuf, strlen(sendbuf), 0, (struct sockaddr *)&otheraddr, sizeof(otheraddr));
}

void event_handler(lv_event_t *e)
{
  // 刷新列表
  printf("refresh list\n");
  // 点击这个按钮发送刷新列表的请求（获取客户端信息）
  send(tcpsock, "getlist", strlen("getlist"), 0);
  // 此时需要等待服务器返回信息，然后刷新列表
  // 先删除列表
  printf("111\n");
  lv_obj_del(list);
  printf("666\n");
  // 在页面左侧创建一个列表，代表好友列表
  list = lv_list_create(scr3);
  lv_obj_set_size(list, 180, 380);
  lv_obj_align(list, LV_ALIGN_LEFT_MID, 0, 0);
  printf("777\n");
  // 给列表设置标签，代表好友列表
  lv_list_add_text(list, "friend list");
  printf("888\n");
  // 给列表添加按钮，刷新好友列表
  // show_chinese(20,btn);
  lv_obj_t *btn = lv_list_add_btn(list, LV_SYMBOL_REFRESH, "refresh");

  // 给这个按钮添加点击事件，刷新好友列表
  lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
  printf("999\n");
  // 链表更新了客户端信息
  char clientbuf[1024];
  // 从链表中读取客户端信息，每读取一个客户端信息，就在列表中创建一个按钮
  cli_list_show(clienthead);
  struct clientlist *p = clienthead; // 指向头结点
  while (p->next != NULL)
  {
    p = p->next;
    // 创建一个按钮
    bzero(clientbuf, sizeof(clientbuf));
    sprintf(clientbuf, "%s:%hu", p->ipaddr, p->clientport);
    btnfriend = lv_list_add_btn(list, NULL, clientbuf);
    // 给这个按钮添加点击事件，表示选择了要发送信息的好友
    lv_obj_add_event_cb(btnfriend, chosefriend, LV_EVENT_CLICKED, strdup(clientbuf));
  }
}